<template>
  <el-dialog
    title="人证合一验证"
    :close-on-click-modal="false"
    :visible.sync="visible"
    @close="dialogClose" ref="dialog">
    <el-row>
      <el-col :span="12">
        <el-row>
          <div class="video-view">
            <video ref="video" v-if="showVedio" width="300" height="300"></video>
            <div class="videotip-box" v-else>
              <span class="video vedio-tip" @click="openCamera">{{cameraTip}}</span>
            </div>
          </div>
        </el-row>
        <el-row>
        <div class="baseparam-box">
          <div class="baseparam-item">
            <div class="baseparam-title">设定阈值</div>
            <div class="baseparam-content">
              <el-input v-model="scoreThreshold" placeholder="相似度阈值"></el-input>
            </div>
          </div>
          <div class="baseparam-item">
            <div class="baseparam-title">读卡器地址</div>
            <div class="baseparam-content">
              <el-input v-model="idCardDeviceUrl" placeholder=""></el-input>
            </div>
          </div>
        </div>
        </el-row>
      </el-col>
      <el-col :span="12">
        <el-row>
          <el-col :span="12">
            <div class="idcard-veryfy">
              <div class="canvas-img-box">
                <canvas class="" ref="snapCanvas" v-show="false" width="300" height="300"></canvas>
                <img :src="base64Tophoto(snapData, snapDefault)">
              </div>
            </div>
          </el-col>
          <el-col :span="12">
            <div class="idcard-veryfy">
              <div class="img-box">
                <img :src="base64Tophoto(idCardInfo.photobase64, idcardDefault)">
              </div>
            </div>
          </el-col>
          </el-row>
          <div style="margin: 20px 0;">
          <el-row>
            <el-col :span="12">
                姓名：{{idCardInfo.name}}
            </el-col>
            <el-col :span="12">
                性别：{{idCardInfo.sex}}
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
                民族：{{idCardInfo.nation}}
            </el-col>
            <el-col :span="12">
                出生日期：{{idCardInfo.born}}
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
                证件号：{{idCardInfo.cardno}}
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              签发机关：{{idCardInfo.police}}
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              有效期限：{{idCardInfo.userlifeb}} - {{idCardInfo.userlifee}}
            </el-col>
          </el-row>
          </div>
          <div style="margin-bottom:20px;height:60px;">
            <el-col :span="24">
              比对分数：{{score}}
            </el-col>
            <el-col :span="24">
              比对结果：<el-tag :type="callValue.verifySeccess? 'success':'danger'">{{comparisonResult(formData.comparisonResult)}}</el-tag>
            </el-col>
          </div>
      </el-col>
      <el-button type="primary" @click="tackPhoto">拍照</el-button>
      <el-button type="primary" @click="getIdCardInfo">身份证读取</el-button>
      <!-- <el-button type="primary" @click="stopCamera">关闭</el-button>
      <el-button type="primary" @click="openCamera">开启</el-button> -->
      <el-button type="primary" @click="faceMath" :loading="varifyBtn.loading">{{varifyBtn.text}}</el-button>
      </el-row>
      <span slot="footer" class="dialog-footer">
        <el-button @click="visible = false">{{ $t('handle.cancel') }}</el-button>
      </span>
  </el-dialog>
</template>

<script>
  import { validatenull } from '@/utils/validate'
  import { existPopulationByIdCard } from "@/utils";
  export default {
    components: {},
    data() {
      return {
        mediaStream: null, // 视频流
        stop: true,
        showVedio: true,
        visible: false,
        idCardDeviceUrl: 'http://127.0.0.1:8080/api/ReadMsg',
        scoreThreshold: 70,
        snapData: '', // 拍照图片数据
        idCardInfo: {}, // 身份证信息
        callValue: {}, // 回传给父组件的拼装的值
        formData: {}, // 对比记录，提交表单用
        score: 0, // 匹配得分
        varifyBtn: { // 比对按钮
          text: '比对',
          loading: false
        },
        // 默认图
        idcardDefault: require("@/assets/img/idcard/idcard-default.png"),
        snapDefault: require("@/assets/img/idcard/snap-default.png"),
        cameraTip: '摄像头已关闭（点击打开）' //摄像头提示信息
      }
    },
    computed: {
      base64Tophoto(){
        return function(base46, defaultPath){
          if(validatenull(base46)){
            return defaultPath
          }
          return 'data:image/jpeg;base64,' + base46;
        }
      },
      comparisonResult(){
        return function(value){
          return validatenull(value) ? '未比对' : value
        }
      }
    },
    created() {
      // this.playVideo()
    },
    beforeDestroy() {
     this.stopCamera()
    },
    methods: {
      // 组件初始化
      init (){
        this.visible = true
        this.openCamera()
        this.getIdCardInfo()
        this.varifyBtn = { // 比对按钮
          text: '比对',
          loading: false
        }
      },
      // 组件关闭
      dialogClose(){
        // 清空数据
        this.snapData = ''// 拍照图片数据
        this.idCardInfo = {}
        this.callValue = {} // 回传给父组件的拼装的值
        this.formData = {} // 对比记录，提交表单用
        this.score = 0 // 匹配得分
        // 关闭摄像头
        this.stopCamera()
      },
      // 打开摄像头播放视频
      playVideo(){
        let con = {
          audio:false,
          video:{
            width: 300,
            height: 300
          }
        }
        this.$nextTick(() => {
          /********************************兼容老的浏览器开始*************************/
          if (navigator.mediaDevices === undefined) {
            navigator.mediaDevices = {};
          }
          if (navigator.mediaDevices.getUserMedia === undefined) {
            navigator.mediaDevices.getUserMedia = function(constraints) {
              // 如果有getUserMedia,就获得它
              let getUserMedia = navigator.getUserMedia ||
                                navigator.webkitGetUserMedia ||
                                navigator.mozGetUserMedia ||
                                navigator.msGetUserMedia;
              // 浏览器没实现这个api，返回reject
              if (!getUserMedia) {
                return Promise.reject(new Error('当前浏览器不支持打开摄像头'));
              }
              // 封装navigator.getUserMedia为promis,保持接口统一
              return new Promise(function(resolve, reject) {
                getUserMedia.call(navigator, constraints, resolve, reject);
              });
            }
          }
          /********************************兼容老的浏览器结束*************************/
          // 播放视频（最新h5API）
          navigator.mediaDevices.getUserMedia(con).then( mediaStream => {
             this.mediaStream = mediaStream
            // 旧的浏览器可能没有srcObject
            if ("srcObject" in this.$refs.video){
               this.$refs.video.srcObject = mediaStream
            } else {
               this.$refs.video.src = window.URL.createObjectURL(stream);
            }
            this.$refs.video.play()
          }, error => {
            console.log("打开摄像头失败",error)
            this.showVedio = false
            this.cameraTip = "摄像头打开失败（点击重试）"
            this.$message.error("打开摄像头失败")
          });
        })
      },
      // 拍照
      tackPhoto(){
        if(!this.showVedio){
          this.$message.error("请先打开摄像头")
          return false;
        }
        this.$nextTick(() => {
          // this.$refs.snapCanvas.getContext("2d").drawImage(this.$refs.video, 0, 0, this.$refs.video.width, this.$refs.video.height)
          this.$refs.snapCanvas.getContext("2d").drawImage(this.$refs.video, 0, 0, 300, 300)
          this.getBase64()
        })
        //  this.getIdCardInfo()
      },
      // 关闭摄像头
      stopCamera(){
        if(this.mediaStream != null){
          this.showVedio = false
          this.cameraTip = "摄像头已关闭（点击打开）"
          this.mediaStream.getTracks()[0].stop()
        }
      },
      // 开启摄像头
      openCamera(){
        this.showVedio = true
        this.playVideo()
      },
      // 获取抓拍图片base64
      getBase64(){
        let imgSrc = this.$refs.snapCanvas.toDataURL("image/png", 1)
        this.snapData = imgSrc.split("base64,")[1]
      },
      // 读取身份证信息
      getIdCardInfo(){
        let _this = this
        this.httpRequest({
          httpUrl: this.idCardDeviceUrl,
          type: 'get'
        }, res => {
          let resJson = JSON.parse(res)
          if(resJson.retcode.indexOf("0x90") == -1){
            this.$message.error("获取身份证信息失败")
            return false;
          }
          existPopulationByIdCard(resJson.cardno).then(({data}) => {
            if(data.dgActualPopulation === null){
              this.$message.error('监护人信息不存在，请核实身份证');
            }else {
              _this.idCardInfo = JSON.parse(res)
              _this.callValue = _this.idCardInfo
              _this.callValue.custodyId = data.dgActualPopulation.populationCoding
              _this.formData.name = _this.idCardInfo.name
              _this.formData.sex = _this.idCardInfo.sex
              _this.formData.nation = _this.idCardInfo.nation
              _this.formData.idNumber = _this.idCardInfo.cardno
              _this.formData.birthday = _this.idCardInfo.born
              _this.formData.address = _this.idCardInfo.address
              _this.formData.police = _this.idCardInfo.police
              _this.formData.userlifeb = _this.idCardInfo.userlifeb
              _this.formData.userlifee = _this.idCardInfo.userlifee
              _this.formData.comparisonType = 1
            }
          })
        }, () => {
          this.$message.error("获取身份证信息失败,请检查读卡器服务是否启动或读卡器url是否正确")
        })
      },
      // 比对记录提交
      submitRecord(){
        let _this = this
        this.$http({
          url: `/dg-ic/ic/combination-witness-testimony/save`,
          method: 'post',
          data: _this.formData
        }).then( res => {
          if(res && res.data.code !== 0){
            this.$message.error(res.data.msg)
            return '';
          }
          // return res.data.data.iconName
        }, reject => {
          this.$message.error("保存记录失败")
          return '';
        })
      },
      // 人脸比对,比对成功后提交比对记录
      faceMath(){
        let _this = this
        if(validatenull(this.snapData)){
          this.$message.error("请先拍照")
          return false;
        }
        if(validatenull(this.idCardInfo.photobase64)){
          this.$message.error("获取身份证图片失败")
          return false;
        }
        // 修改按钮状态
        this.varifyBtn.text = '比对中'
        this.varifyBtn.loading = true
        this.$http({
          url: `/dg-ic/ic/combination-witness-testimony/face/mach`,
          method: 'post',
          data:{
            image1: _this.snapData,
            image2: _this.idCardInfo.photobase64
          }
        }).then( res => {
          if(res && res.data.code !== 0){
            this.$message.error(res.data.msg)
            return false;
          }
          let resData = JSON.parse(res.data.data)
          _this.score = resData.score.toFixed(3)
          _this.formData.comparisonResult = '人证不匹配'
          _this.formData.setThreshold = _this.scoreThreshold
          _this.formData.comparisonThreshold = resData.score
          _this.callValue.verifySeccess = false
          _this.callValue.score = resData.score
          if(resData.score >= _this.scoreThreshold){
            _this.formData.comparisonResult = '人证匹配'
            _this.callValue.verifySeccess = true
          }
          // 1 拍照图和身份证图片上传
          _this.$http({
            url: `/dg-ic/ic/file/upload/multi/base64`,
            method: 'post',
            data: [_this.snapData, _this.idCardInfo.photobase64],
          }).then( res1 => {
            _this.varifyBtn.text = '比对'
            _this.varifyBtn.loading = false
             if (res1.data && res1.data.code !== 0) {
               _this.$message.error("图片上传失败")
               return false;
             }
             // 拍照图片
             _this.formData.portraitPhoto = res1.data.data[0].iconName
             _this.callValue.portraitPhoto =  _this.formData.portraitPhoto
             // 身份证图片
            _this.formData.idPhoto = res1.data.data[1].iconName
            _this.callValue.idPhoto =  _this.formData.idPhoto
            // 3 对比记录上传
            _this.submitRecord()
            if(_this.score >= _this.scoreThreshold){
              // 触发父组件
               _this.callTheValue()
              // 关闭弹窗
              _this.visible = false
              _this.$message({
                message: '人证合一比对成功，比对分数: '+ _this.score,
                type: 'success'
              })
            }

          }, reject1 => {
            _this.varifyBtn.text = '比对'
            _this.varifyBtn.loading = false
            _this.$message.error("图片上传失败")
          })
        }, reject => {
          _this.varifyBtn.text = '比对'
          _this.varifyBtn.loading = false
          _this.$message.error("人脸比对失败")
        })
      },
      // 传值给父组件
      callTheValue(){
        this.$emit("verifyResult", this.callValue)
      },
      // 原生ttp请求
      httpRequest(paramObj,fun,errFun) {
        var xmlhttp = null;
        /*创建XMLHttpRequest对象，
        *老版本的 Internet Explorer（IE5 和 IE6）使用 ActiveX 对象：new ActiveXObject("Microsoft.XMLHTTP")
        * */
        if(window.XMLHttpRequest) {
          xmlhttp = new XMLHttpRequest();
        }else if(window.ActiveXObject) {
          xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        /*判断是否支持请求*/
        if(xmlhttp == null) {
          // alert('你的浏览器不支持XMLHttp');
          return;
        }
        /*请求方式，并且转换为大写*/
        var httpType = (paramObj.type || 'GET').toUpperCase();
        /*数据类型*/
        var dataType = paramObj.dataType || 'json';
        /*请求接口*/
        var httpUrl = paramObj.httpUrl || '';
        /*是否异步请求*/
        var async = paramObj.async || true;
        /*请求参数--post请求参数格式为：foo=bar&lorem=ipsum*/
        var paramData = paramObj.data || [];
        var requestData = '';
        for(var name in paramData) {
          requestData += name + '='+ paramData[name] + '&';
        }
        requestData = requestData == '' ? '' : requestData.substring(0,requestData.length - 1);
        /*请求接收*/
        xmlhttp.onreadystatechange = function() {
          if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            /*成功回调函数*/
            fun(xmlhttp.responseText);
          } else if(xmlhttp.readyState == 4 && xmlhttp.status !== 200){
            /*失败回调函数*/
            errFun();
          } else {
            errFun;
          }
        }
        /*接口连接，先判断连接类型是post还是get*/
        if(httpType == 'GET') {
          xmlhttp.open("GET",httpUrl,async);
          xmlhttp.send(null);
        }else if(httpType == 'POST'){
          xmlhttp.open("POST",httpUrl,async);
          //发送合适的请求头信息
          xmlhttp.setRequestHeader("Content-type", "application/json");
          xmlhttp.send(requestData);
        }}
    }
  };
</script>

<style lang="scss" scoped>
  .video-view{
    width: 100%;
    height: 300px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 30px;
    video{
      width: 300px;
      height: 300px;
      border: 1px solid #f1f1f1;
    }
    .videotip-box{
      width: 300px;
      height: 300px;
      border: 1px solid #f1f1f1;
      display: flex;
      justify-content: center;
      align-items: center;
      .vedio-tip{
        cursor: pointer;
        font-size: 18px;
        color: #aaa;
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }

  }
  .baseparam-box{
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    .baseparam-item{
      width: 350px;
      display: flex;
      margin-bottom: 10px;
      .baseparam-title{
        width: 80px;
        display: flex;
        align-items: center;
      }
      .baseparam-content{
        width: 270px;
      }
    }
  }
  .idcard-veryfy{
/*     display: flex;
    justify-content: center;
    align-items: center; */
    canvas{
      width: 300px;
      height: 130px;
      border: 1px solid #f1f1f1;
    }
    .img-box{
      width: 105px;
      height: 130px;
      border: 1px solid #f1f1f1;
    }
    .canvas-img-box{
      width: 130px;
      height: 130px;
      border: 1px solid #f1f1f1;
      img{
        max-height: 130px;
      }
    }

  }
</style>
